package Proxy2;

import Proxy2.Staticproxy.ProgramerProxy;

import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by 0171093 on 2018/2/2.
 * 代理模式
 * 优点
 * 1 能够协调调用者和被调用者，在一定程度上降低了系统的耦合度。
 * 2 客户端可以针对抽象主题角色进行编程，增加和更换代理类无须修改源代码，符合开闭原则，系统具有较好的灵活性和可扩展性。
 * <p/>
 * 缺点
 * 1 由于在客户端和真实主题之间增加了代理对象，因此有些类型的代理模式可能会造成请求的处理速度变慢
 * 2 实现代理模式需要额外的工作，而且有些代理模式的实现过程较为复杂，例如远程代理。
 * <p/>
 * <p/>
 * 静态代理
 * 由程序员创建或工具生成代理类的源码，再编译代理类。
 * 所谓静态也就是在程序运行前就已经存在代理类的字节码文件，代理类和委托类的关系在运行前就确定了。
 * 产品经理（客户）需要实现产品需求，于是找技术leader（代理）来找程序猿（实际执行者）写代码。
 * 对于产品经理来说，技术leader就是负责完成对应需求的人，对于产品来说，具体是谁完成怎样完成，并不关心。
 * <p/>
 * <p/>
 * 动态代理(ProductManager)
 * 动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成，
 * 所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
 * 创建动态代理过程：
 * 1,通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…);
 * 2,通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
 * Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});
 * 3,通过反射机制获取动态代理类的构造函数，其参数类型是调用处理器接口类型
 * Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
 * 4,通过构造函数创建代理类实例，此时需将调用处理器对象作为参数被传入
 * Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
 * 为了简化对象创建过程，Proxy类中的newInstance方法封装了2~4，只需两步即可完成代理对象的创建。
 * 生成的ProxySubject继承Proxy类实现Subject接口，实现的Subject的方法实际调用处理器的invoke方法，
 * 而invoke方法利用反射调用的是被代理对象的的方法（Object result=method.invoke(proxied,args)）
 */
public class main {


    public static void main(String[] args) {

        //静态代理模式
        ProgramerProxy proxy = new ProgramerProxy();
        proxy.code();
    }

}
